﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Threading;


namespace Simple2DSample
{


    // http://msdn.microsoft.com/ko-kr/library/yy12yx1f.aspx


    public class SyncEvents
    {
        public SyncEvents()
        {

            _newItemEvent = new AutoResetEvent(false);
            _exitThreadEvent = new ManualResetEvent(false);
            _eventArray = new WaitHandle[2];
            _eventArray[0] = _newItemEvent;
            _eventArray[1] = _exitThreadEvent;
        }

        public EventWaitHandle ExitThreadEvent
        {
            get { return _exitThreadEvent; }
        }
        public EventWaitHandle NewItemEvent
        {
            get { return _newItemEvent; }
        }
        public WaitHandle[] EventArray
        {
            get { return _eventArray; }
        }

        private EventWaitHandle _newItemEvent;
        private EventWaitHandle _exitThreadEvent;
        private WaitHandle[] _eventArray;
    }


    public class MyThreadPool
    {

     

        static public MyThreadPool I = new MyThreadPool();


        public MyThreadPool()
        {
            ThreadStart ts = new ThreadStart(ThreadRun);
            Thread thread = new Thread(ts);
            thread.Start(); 
        }

        Queue<ThreadJob> _queue = new Queue<ThreadJob>();
        SyncEvents _syncEvents = new SyncEvents();


        public void ThreadRun()
        {
            ThreadJob job;
            while (WaitHandle.WaitAny(_syncEvents.EventArray) != 1)
            {
                while (0 < _queue.Count)
                {
                    lock (((ICollection)_queue).SyncRoot)
                    {
                        job = _queue.Dequeue();
                    }
                    job.Run();
                }

            } 

        }

        public void Exit()
        {
            _syncEvents.ExitThreadEvent.Set();
        }


        public void AddJob(ThreadJob job)
        {
             lock (((ICollection)_queue).SyncRoot)
            {
                    _queue.Enqueue(job);
                    _syncEvents.NewItemEvent.Set();
            }

        }

    }

}
